package com.cskaoyan.service.admin.role.impl;

import com.cskaoyan.bean.*;
import com.cskaoyan.bean.bo.admin.role.AdminRolePermissionBo;
import com.cskaoyan.bean.po.admin.role.MarketPermissionDetails;
import com.cskaoyan.bean.po.admin.role.MarketRolePermission;
import com.cskaoyan.bean.vo.admin.role.AdminRoleVo;
import com.cskaoyan.bean.vo.admin.role.options.AdminRoleOptionsVo;
import com.cskaoyan.bean.vo.admin.role.permission.AdminPermissionCategoryVo;
import com.cskaoyan.bean.vo.admin.role.permission.AdminPermissionDetailVo;
import com.cskaoyan.bean.vo.admin.role.permission.AdminPermissionModuleVo;
import com.cskaoyan.bean.vo.admin.role.permission.AdminPermissionVo;
import com.cskaoyan.mapper.MarketRoleMapper;
import com.cskaoyan.mapper.admin.role.MarketPermissionDetailsMapper;
import com.cskaoyan.mapper.admin.role.MarketRolePermissionMapper;
import com.cskaoyan.service.admin.role.AdminRoleService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author MoJunXiang
 * @since 2022/09/08 17:07
 */
@Service
public class AdminRoleServiceImpl implements AdminRoleService {

    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

    @Autowired
    MarketRoleMapper marketRoleMapper;
    @Autowired
    MarketRolePermissionMapper marketRolePermissionMapper;
    @Autowired
    MarketPermissionDetailsMapper marketPermissionDetailsMapper;


    /**
     * @function_name list
     * @param page
     * @param limit
     * @param sort
     * @param order
     * @param name
     * @idea 返回所有 **角色** 的数据
     * @return com.cskaoyan.bean.vo.admin.role.AdminRoleVo
     * @author MoJunXiang
     * @since 2022/09/08 19:47
     */
    @Override
    public AdminRoleVo list(Integer page, Integer limit, String sort, String order, String name) {
        // 返回值
        AdminRoleVo<MarketRole> roleVo = new AdminRoleVo<>();
        ArrayList<MarketRole> list = new ArrayList<>();
        roleVo.setList(list);



        // 从 数据库 中拿数据
        MarketRoleExample example = new MarketRoleExample();
        example.setOrderByClause(sort + "   " + order);
        MarketRoleExample.Criteria criteria = example.createCriteria();
        criteria.andDeletedEqualTo(false);

        PageHelper.startPage(page, limit);

        List<MarketRole> marketRoleList = marketRoleMapper.selectByExample(example);

        PageInfo<MarketRole> pageInfo = new PageInfo<>(marketRoleList);




        // 将转换后的值放入 roleVo 中
        roleVo.setLimit(limit);
        roleVo.setPage(page);
        roleVo.setPages(pageInfo.getPages());
        roleVo.setTotal(((int) pageInfo.getTotal()));
        // 处理从数据库中拿出的数据，将其转换成对应的格式放入 list 中
        for (MarketRole role : marketRoleList) {
            Date addTimeDate = role.getAddTime();
            Date updateTimeDate = role.getUpdateTime();
            Date add_time = formatDate(addTimeDate);
            Date update_time = formatDate(updateTimeDate);

            role.setAddTime(add_time);
            role.setUpdateTime(update_time);

            list.add(role);
        }


        return roleVo;
    }


    /**
     * @function_name options
     * @idea 返回 **market_role表** 中需要的所有 **角色** 的 *id* 和 *name*
     * @return com.cskaoyan.bean.vo.admin.role.AdminRoleVo
     * @author MoJunXiang
     * @since 2022/09/08 20:40
     */
    @Override
    public AdminRoleVo options() {
        // 返回值
        AdminRoleVo<AdminRoleOptionsVo> roleVo = new AdminRoleVo<>();
        ArrayList<AdminRoleOptionsVo> list = new ArrayList<>();
        roleVo.setList(list);


        // 从 数据库 中拿出数据
        List<MarketRole> marketRoleList = marketRoleMapper.selectByExample(new MarketRoleExample());


        // 将从数据库中拿出的数据经转换后放入 roleVo
        for (MarketRole role : marketRoleList) {
            AdminRoleOptionsVo optionsVo = new AdminRoleOptionsVo(role.getName(), role.getId());
            list.add(optionsVo);
        }
        int size = marketRoleList.size();
        roleVo.setTotal(size);
        roleVo.setPage(1);
        roleVo.setLimit(size);
        roleVo.setPages(1);



        return roleVo;
    }



    /**
     * @function_name create
     * @param paraMap
     * @idea 获得请求中包含的信息 *name* 和 *desc* ，将其放入新的 **MarketRole对象role** 中，并且为其设置 *add_time* 、 *update_time*  ，将 **role** 插入数据库，并从数据库获得其  *id*  。将数据完整的 **role** 返回给前端。
     * @return com.cskaoyan.bean.MarketRole
     * @author MoJunXiang
     * @since 2022/09/08 21:21
     */
    @Override
    public MarketRole create(Map<String, String> paraMap) {
        // 返回值
        MarketRole role = new MarketRole();
        Date add_time = new Date();
        add_time = formatDate(add_time);
        Date update_time = add_time;
        role.setAddTime(add_time);
        role.setUpdateTime(update_time);
        role.setDeleted(false);
        role.setEnabled(false);
        role.setDesc(paraMap.get("desc"));
        role.setName(paraMap.get("name"));

        // 将新数据插入到 market_role表 中
        int insert = marketRoleMapper.insertSelective(role);


        // 将从 插入数据库 中获得的返回的 id 放入 role 中


        return role;
    }



    /**
     * @function_name update
     * @param role
     * @idea 将在管理系统中改变的 **role** 数据更新到数据库中的 **market_role** 表中
     * @return void
     * @author MoJunXiang
     * @since 2022/09/09 14:01
     */
    @Override
    public void update(MarketRole role) {
        Date addTime = role.getAddTime();
        Date updateTime = role.getUpdateTime();
        addTime = formatDate(addTime);
        updateTime = formatDate(updateTime);
        role.setAddTime(addTime);
        role.setUpdateTime(updateTime);

        MarketRoleExample example = new MarketRoleExample();
        MarketRoleExample.Criteria criteria = example.createCriteria();
        criteria.andIdEqualTo(role.getId());

        marketRoleMapper.updateByExampleSelective(role, example);
    }


    /**
     * @function_name delete
     * @param role
     * @idea 将指定 **角色（管理员）** 的信息传入， *逻辑删除（即令其 deleted=true）* 指定 *id* 的 **角色（管理员）**
     * @return void
     * @author MoJunXiang
     * @since 2022/09/09 14:04
     */
    @Override
    public void delete(MarketRole role) {
        Date addTime = role.getAddTime();
        Date updateTime = role.getUpdateTime();
        addTime = formatDate(addTime);
        updateTime = formatDate(updateTime);
        role.setAddTime(addTime);
        role.setUpdateTime(updateTime);

        role.setDeleted(true);

        MarketRoleExample example = new MarketRoleExample();
        MarketRoleExample.Criteria criteria = example.createCriteria();
        criteria.andIdEqualTo(role.getId());



        marketRoleMapper.updateByExampleSelective(role, example);

    }


    /**
     * @function_name permissions（POST）
     * @param bo
     * @idea 将传来的数据放入 **market_role_permission表**
     * @return void
     * @author MoJunXiang
     * @since 2022/09/09 17:35
     */
    @Override
    public void permissions(AdminRolePermissionBo bo) {
        try {
            int roleId = bo.getRoleId();
            List<String> list = bo.getPermissions();

            // 存放要插入 market_role_permission表 中数据的 线性表
            ArrayList<MarketRolePermission> rolePermissionList = new ArrayList<>();

            // 将填充完的数据插入到  market_role_permission表 中
            for (String permission_detail_id_str : list) {
                // 从 market_permission_details表 中拿到需要的数据——指 permission_detail_id

                MarketPermissionDetailsColumns marketPermissionDetailsColumns = new MarketPermissionDetailsColumns();
                marketPermissionDetailsColumns.addColumn("id");

                MarketPermissionDetails permissionDetailsExample = new MarketPermissionDetails();
                permissionDetailsExample.setAid_str(permission_detail_id_str);

                MarketPermissionDetailsConditions marketPermissionDetailsConditions = new MarketPermissionDetailsConditions();
                marketPermissionDetailsConditions.init(permissionDetailsExample);

                List<MarketPermissionDetails> permissionDetailsList = marketPermissionDetailsMapper.selectColumnsByAndCondition(marketPermissionDetailsColumns, marketPermissionDetailsConditions);

                MarketPermissionDetails permissionDetails = permissionDetailsList.get(0);
                Integer id = permissionDetails.getId();
                String aid_str = permissionDetails.getAid_str();

                MarketRolePermission rolePermission = new MarketRolePermission();
                rolePermission.setPermission_detail_id(id);
                rolePermission.setRole_id(roleId);
                rolePermission.setPermission_detail_id_str(aid_str);

                rolePermissionList.add(rolePermission);
            }

            // 将填充完数据的 list 插入到 market_role_permission表 中
            marketRolePermissionMapper.insertList(rolePermissionList);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }




    /**
     * @function_name permissions(GET)
     * @param roleId
     * @idea 返回 **market_permission_details** 表中的所有数据和 **market_role_permission** 表中 *role_id* 为对应值的所有数据
     * @return com.cskaoyan.bean.vo.admin.role.permission.AdminPermissionVo
     * @author MoJunXiang
     * @since 2022/09/10 20:29
     */
    @Override
    public AdminPermissionVo permissions(Integer roleId) {
        // 返回值
        AdminPermissionVo permissionVo = new AdminPermissionVo();
        ArrayList<AdminPermissionModuleVo> systemPermissions = new ArrayList<>();
        ArrayList<String> assignedPermissions = new ArrayList<>();
        permissionVo.setSystemPermissions(systemPermissions);
        permissionVo.setAssignedPermissions(assignedPermissions);
        try {


            // 从 数据库 中拿出数据
            MarketPermissionDetailsColumns marketPermissionDetailsColumns = new MarketPermissionDetailsColumns();
            marketPermissionDetailsColumns.addAllColumns();
            List<MarketPermissionDetails> permissionDetailsList = marketPermissionDetailsMapper.selectColumnsByAndCondition(marketPermissionDetailsColumns, new MarketPermissionDetailsConditions());

            MarketRolePermissionColumns columns = new MarketRolePermissionColumns();
            columns.addColumn("permission_detail_id_str");
            MarketRolePermissionConditions conditions = new MarketRolePermissionConditions();
            MarketRolePermission rolePermissionExample = new MarketRolePermission();
            rolePermissionExample.setRole_id(roleId);
            conditions.init(rolePermissionExample);

            List<MarketRolePermission> rolePermissionList = marketRolePermissionMapper.selectColumnsByAndConditions(columns, conditions);


            /*TODO:
            *   1、将从数据库中拿出的数据从 以一层存储结构存储三层逻辑结构 的模式
            *       转换为 以三层存储结构存储三层逻辑结构 的模式，即把数据从 list
            *       中转换到用 HashMap对象存储 的树中
        *       2、把用 HasnMap对象存储 的树里对应层级的数据，放入
         *           AdminPermissionVo对象permissionVo 中的对应层级，
         *          即进行数据封装*/
            /*1、将从数据库中拿出的数据从 以一层存储结构存储三层逻辑结构 的模式
             *   转换为 以三层存储结构存储三层逻辑结构 的模式，即把数据从 list
             *   中转换到用 HashMap对象存储 的树中*/
            HashMap<String, Map> permissionDetailsTree = createPermissionDetailsTree(permissionDetailsList);
            /*2、把用 HasnMap对象存储 的树里对应层级的数据，放入
             *    AdminPermissionVo对象permissionVo 中的对应层级，
             *   即进行数据封装*/
            // 将数据封装进 systemPermissions线性表 中
            Set<String> mid_strSet = permissionDetailsTree.keySet();
            for (String mid_str : mid_strSet) {
                Map moduleMap = permissionDetailsTree.get(mid_str);
                Set cid_strSet = moduleMap.keySet();

                // 设置 AdminPermissionModuleVo对象permissionModuleVo
                AdminPermissionModuleVo permissionModuleVo = new AdminPermissionModuleVo();
                permissionModuleVo.setId(mid_str);
                permissionModuleVo.setLabel(mid_str);
                ArrayList<AdminPermissionCategoryVo> children = new ArrayList<>();
                permissionModuleVo.setChildren(children);

                for (Object cidStr : cid_strSet) {
                    String cid_str = (String) cidStr;
                    List categoryDetailsList = (List) moduleMap.get(cid_str);

                    // 设置 AdminPermissionCategoryVo对象permissionCategoryVo
                    AdminPermissionCategoryVo permissionCategoryVo = new AdminPermissionCategoryVo();
                    permissionCategoryVo.setId(cid_str);
                    permissionCategoryVo.setLabel(cid_str);
                    permissionCategoryVo.setChildren(categoryDetailsList);

                    children.add(permissionCategoryVo);
                }

                /*将封装好的 AdminPermissionModuleVo对象permissionModuleVo 放入
                *  systemPermissions线性表 中*/
                systemPermissions.add(permissionModuleVo);
            }


            // 将数据封装进 assignedPermissions线性表 中
            for (MarketRolePermission rolePermission : rolePermissionList) {
                String permission_detail_id_str = rolePermission.getPermission_detail_id_str();
                assignedPermissions.add(permission_detail_id_str);
            }

        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } finally {
            return permissionVo;
        }
    }

    private HashMap<String, Map> createPermissionDetailsTree(List<MarketPermissionDetails> permissionDetailsList) {
        // 根
        HashMap<String, Map> permissionDetailsTree = new HashMap<>();
        for (MarketPermissionDetails permissionDetails : permissionDetailsList) {
            String mid_str = permissionDetails.getMid_str();

            // module层<——>第一层
            Map moduleMap = permissionDetailsTree.get(mid_str);
            if (moduleMap == null) {

                moduleMap = new HashMap<String, ArrayList>();
                // 从 根 往 第一层/module层 生长
                permissionDetailsTree.put(mid_str, moduleMap);

                String cid_str = permissionDetails.getCid_str();
                // category层<——>第二层
                List categoryDetailsList = (ArrayList) moduleMap.get(cid_str);
                if (categoryDetailsList == null) {

                    categoryDetailsList = new ArrayList<AdminPermissionDetailVo>();
                    // 从 第一层/module层 往 第二层/category层 生长
                    moduleMap.put(cid_str, categoryDetailsList);
                }
                // 如果 moduleMap 不为空，但 categoryDetailsList 为空
            } else {
                String cid_str = permissionDetails.getCid_str();
                // category层<——>第二层
                List categoryDetailsList = (ArrayList) moduleMap.get(cid_str);
                if (categoryDetailsList == null) {

                    categoryDetailsList = new ArrayList<AdminPermissionDetailVo>();
                    // 从 第一层/module层 往 第二层/category层 生长
                    moduleMap.put(cid_str, categoryDetailsList);
                }
            }
            /* 第二层/category层 填充数据。
            * 该过程无论是上面四种情况哪种情况都要执行的，所以把它提出来*/
            String cid_str = permissionDetails.getCid_str();
            ArrayList categoryDetailsList = (ArrayList) moduleMap.get(cid_str);

            String aid_str = permissionDetails.getAid_str();
            String aid_label = permissionDetails.getAid_label();
            String api = permissionDetails.getApi();
            AdminPermissionDetailVo detailVo = new AdminPermissionDetailVo(aid_str, aid_label, api);
            categoryDetailsList.add(detailVo);
        }
        return permissionDetailsTree;
    }


    private Date formatDate(Date time) {
        String dateStr = dateFormat.format(time);
        Date date = null;
        try {
            date = dateFormat.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }



}
